package main;

import informationextraction.ComponentIDExtraction;
import informationextraction.ECastExtraction;
import informationextraction.ICastExtraction;
import informationextraction.InfoExtraction;
import informationextraction.SharedUserIdExtraction;
import informationextraction.UsePermissionExtraction;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

import javax.swing.JDialog;

import javaparser.Java7InformationListener;
import javaparser.Java7ExtractInformationListener;
import javaparser.Java7Lexer;
import javaparser.Java7Parser;
import javaparser.Java7Parser.ArgumentsContext;
import javaparser.Java7Parser.IdentifierTypeArgumentContext;
import javaparser.Java7Parser.ImportDeclarationContext;
import javaparser.Java7Parser.LocalVariableDeclarationContext;
import javaparser.Java7Parser.PackageDeclarationContext;
import javaparser.Java7Parser.PrimaryContext;

import org.antlr.v4.runtime.ANTLRInputStream;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.ParserRuleContext;
import org.antlr.v4.runtime.RuleContext;
import org.antlr.v4.runtime.atn.PredictionMode;
import org.antlr.v4.runtime.misc.Utils;
import org.antlr.v4.runtime.tree.ParseTree;
import org.antlr.v4.runtime.tree.ParseTreeWalker;

import commandset.ECast;
import commandset.ICast;

import xmlparser.XMLExtractInformationListener;
import xmlparser.XMLInformationListener;
import xmlparser.XMLLexer;
import xmlparser.XMLParser;

public class Test {
	public static void main(String[] args) throws Exception {
		Test testing = new Test();
		//testing.testJava();
		testing.testXML();
	}

	public void testJava() throws IOException, InterruptedException,
			NullPointerException, ExecutionException {
		InputStream in = getClass().getClassLoader().getResourceAsStream(
				"testfiles/ProjectB.java.txt");
		ANTLRInputStream input = new ANTLRInputStream(in);
		// create a lexer that feeds off of input CharStream
		Java7Lexer lexer = new Java7Lexer(input);
		// create a buffer of tokens pulled from the lexer
		CommonTokenStream tokens = new CommonTokenStream(lexer);
		// create a parser that feeds off the tokens buffer
		Java7Parser parser = new Java7Parser(tokens);
		ParserRuleContext tree = parser.compilationUnit();
		// ParseTree tree = parser.compilationUnit(); // begin parsing at init
		// rule
		// Future<JDialog> future = tree.inspect(parser);
		// Utils.waitForClose(future.get());

		// Create a generic parse tree walker that can trigger callbacks
		ParseTreeWalker walker = new ParseTreeWalker();

		Java7InformationListener info = new Java7InformationListener();

		Java7ExtractInformationListener ext = new Java7ExtractInformationListener();
		// Walk the tree created during the parse, trigger callbacks
		walker.walk(info, tree);
		InfoExtraction info_extrxct = new InfoExtraction(info);
		ECastExtraction ecast = new ECastExtraction(info);
		ecast.setInfoForECast();
		ICastExtraction icast = new ICastExtraction(info);
		icast.setInfoForICast();
		// printListLocal(ecast.getListLocalVariableDeclarationOfIntent());
		List<LocalVariableDeclarationContext> list1 = info_extrxct.getInfo()
				.getLocal_variable_declaration();
		for (int i = 0; i < list1.size(); i++) {
			System.out.println(list1.get(i).getRuleContext().getText());
		}
		 System.out.println(info_extrxct
		 .getArgumentsContextOfIntentVariable("intent").getRuleContext()
		 .getText());
		// System.out.println(info_extrxct
		// .getListMethodCallOfIntentVariablesContainsComponentName(
		// "intent").get(0).getText());
		// System.out.println(info_extrxct
		// .getListMethodCallOfIntentVariablesContainsSetActionMethod(
		// "intent").get(0).Identifier(1));
		// System.out.println(info_extrxct
		// .getPrimaryContextFromArgumentContextOfIntentVariable(
		// "intent").get(0).Identifier(0));
		try {
			System.out.println(info_extrxct
					.getPrimaryContextFromArgumentContextOfIntentVariable(
							"intent").get(0).getRuleContext().getText());
		} catch (IndexOutOfBoundsException e) {
			// TODO: handle exception
			System.out.println("List empty");
		}
		// printListPrimary(info.getList_primary());
		// ecast.setInfoForECast();
		// icast.setInfoForICast();
		List<ECast> list_ecast = ecast.getEcast();
		List<ICast> list_icast = icast.getList_icast();
		// System.out.println(info.getLocal_variable_declaration().size());
		// printListLocal(info.getLocal_variable_declaration());
		System.out.println("list_ecast size: " + list_ecast.size());
		System.out.println("list_icast size: " + list_icast.size());
		// System.out.println(ecast.getComponentID("intent1"));
		// System.out.println(list_ecast.get(0).printECast());
		if (!icast.getList_icast().isEmpty())
			System.out.println(list_icast.get(0).printICast());
		if (!ecast.getEcast().isEmpty()) {
			List list = ecast.getEcast();
			for (int i = 0; i < list.size(); i++) {
				System.out.println(list_ecast.get(i).printECast());
			}
		}
		// System.out.println(list_ecst.get(1).printECastWithResourceUI());
		// printListObject(ecast.getInfo().getList_argrument());
		// printListObject(info.getList_argrument());

		// ECastExtraction ecast_extraction = new ECastExtraction(ecast);
		 printListPrimary(info_extrxct.getListMethodCallOfIntentVariablesContainsComponentName("intent1"));
		 printListPrimary(info_extrxct.getListMethodCallOfIntentVariablesContainsSetActionMethod("intent1"));
		// printListLocal(ecast_extraction.getListLocalVariableDeclarationOfIntent("intent2"));
		 printStringList(info_extrxct.getListVariableNameOfIntent());
		 printListLocal(info_extrxct.getListLocalVariableDeclarationOfIntent());

		// PackageDeclarationContext pac = ecast.getPackage_declaration();
		// printList(ecast.getList_import());
		// List<LocalVariableDeclarationContext> local =
		// ecast.getLocal_variable_declaration();
		// printListLocal(local);
		// printListIndentify(local.)
		// System.out.println("here "+
		// local.get(0).type().classOrInterfaceType().identifierTypeArgument(0).getText());
		// System.out.print(ecast.getNormal_class_declaration().type()
		// .classOrInterfaceType().identifierTypeArgument());
		// printListIndentify(ecast.getList_id_type_agrument());
		// System.out.println("pac = " + pac.qualifiedName().Identifier(2));
		// ecast.s;
		// System.out.println("heloo"); // print a \n after translation
	}

	public void testXML() throws IOException, InterruptedException,
			ExecutionException, NullPointerException {
		InputStream in = getClass().getClassLoader().getResourceAsStream(
				"testfiles/AndroidManifestT1B.xml.txt");
		ANTLRInputStream input = new ANTLRInputStream(in);
		// create a lexer that feeds off of input CharStream
		XMLLexer lexer = new XMLLexer(input);
		// create a buffer of tokens pulled from the lexer
		CommonTokenStream tokens = new CommonTokenStream(lexer);
		// create a parser that feeds off the tokens buffer
		XMLParser parser = new XMLParser(tokens);
		ParserRuleContext tree = parser.document(); // begin parsing at init
													// rule
		// Future<JDialog> future = tree.inspect(parser);
		// Utils.waitForClose(future.get());
		// Create a generic parse tree walker that can trigger callbacks
		ParseTreeWalker walker = new ParseTreeWalker();
		XMLInformationListener listener = new XMLInformationListener();
		XMLExtractInformationListener liste_ = new XMLExtractInformationListener();
		// Walk the tree created during the parse, trigger callbacks
		walker.walk(liste_, tree);
		SharedUserIdExtraction shareduserid = new SharedUserIdExtraction(
				listener);
		
		UsePermissionExtraction use_per = new UsePermissionExtraction(listener);
		shareduserid.setSharedUserID();
		use_per.setUsePermission();
		ComponentIDExtraction comp_ex = new ComponentIDExtraction(listener);
		comp_ex.setComponentID();
		
		if (!use_per.getListUsePermission().isEmpty()) {
			use_per.getListUsePermission().get(0).printUsePermission();
			// use_per.getListUsePermission().get(1).printUsePermission();
		}
		if (!shareduserid.getShared_user_id().isEmpty())
			shareduserid.getShared_user_id().printSharedUserID();
		if (!comp_ex.getComponentID().isEmpty())
			comp_ex.getComponentID().printComponentID();
		// System.out.println("heloo"); // print a \n after translation
	}

	public void printList(List<ImportDeclarationContext> list) {

		Iterator<ImportDeclarationContext> itr = list.iterator();
		System.out.println("---------- List import declaration -----------");
		while (itr.hasNext()) {
			ImportDeclarationContext im = itr.next();
			for (int i = 0; i < im.Identifier().size(); i++) {
				if (i == im.Identifier().size() - 1) {
					System.out.print(im.Identifier(i));
					break;
				}
				System.out.print(im.Identifier(i) + ".");
			}
			System.out.println();

		}
	}

	public void printListObject(List list) {

		Iterator itr = list.iterator();
		if (list.get(0) instanceof ArgumentsContext) {
			System.out.println("---------- List Object -----------");
			while (itr.hasNext()) {
				ArgumentsContext im = (ArgumentsContext) itr.next();
				System.out.println(im.getRuleContext().getText());
			}
		}
	}

	public void printListIndentify(List<IdentifierTypeArgumentContext> list) {

		Iterator<IdentifierTypeArgumentContext> itr = list.iterator();
		System.out
				.println("---------- List Identifier Type Argument -----------");
		while (itr.hasNext()) {
			IdentifierTypeArgumentContext im = itr.next();
			System.out.println(im.getText());
		}
	}

	public void printListPrimary(List<PrimaryContext> list) {

		Iterator<PrimaryContext> itr = list.iterator();
		System.out.println("---------- List Primary -----------");
		while (itr.hasNext()) {
			PrimaryContext im = itr.next();
			System.out.println(im.getRuleContext().getText());
		}
	}

	public void printListLocal(List<LocalVariableDeclarationContext> list) {

		Iterator<LocalVariableDeclarationContext> itr = list.iterator();
		System.out
				.println("---------- List Local Variable Declaration -----------");
		while (itr.hasNext()) {
			LocalVariableDeclarationContext im = itr.next();
			System.out.println(im.getRuleContext().getText());
			String str = new String();
			// try {
			// System.out.println(im.type().classOrInterfaceType()
			// .identifierTypeArgument().get(0).getRuleContext()
			// .getText());// .get(0).getRuleContext()
			// } catch (NullPointerException e) {
			// //str = null;
			// im = itr.next();
			// // TODO: handle exception
			// }
			// .getText();
			// if (str != null)
			// System.out.println(im.type().classOrInterfaceType()
			// .identifierTypeArgument().get(0).getRuleContext()
			// .getText());
			// printListIndentify(im.type().classOrInterfaceType()
			// .identifierTypeArgument());
		}
	}

	public void printStringList(List<String> list) {
		Iterator<String> itr = list.iterator();
		System.out.println("---------- List String -----------");
		while (itr.hasNext()) {
			String im = itr.next();
			System.out.println(im + " ");
		}
	}

}
